package spl.manager;


import java.io.*;
import java.net.*;

import spl.utils.GlobalLogger;
/**
 * @author avikam
 *
 */
public class WorkManager {
	static final String SERVER_NAME = "Photohut";
	static final int DEFAULT_LISTENING_PORT = 7070;
	static final int DEFAULT_MAX_POOLED = 5;
	private static final String DEFAULT_LOG_PATH = "deafultLog.xml";
	
	private static JobDistributor localJobDistributor;

	@SuppressWarnings("unused")
	private static InetAddress serverInetAddress;
    private static int listeningPort;

	private static ServerSocket serverSocket;
	
	/**
	 * Open a server socket and start listening without timeout.
	 * @param listenPort a port to listen
	 * @param handler a connection handler, i.e ThreadedConnectionHandler
	 */
	public static void serveForever(int listenPort, ConnectionHandler handler) {

        // init job distributor settings:
        WorkManager.localJobDistributor = new JobDistributor();
		
		try {
			WorkManager.serverSocket = new ServerSocket(listenPort, WorkManager.DEFAULT_MAX_POOLED);
			Socket incomingConnection = null;
			
			// Save inet address
			WorkManager.serverInetAddress = serverSocket.getInetAddress();
            WorkManager.listeningPort = listenPort;

			
			while (true) {
				incomingConnection = serverSocket.accept();
				handler.handleConnection(incomingConnection);
			}
		} catch (BindException e) {
			GlobalLogger.getLogger().severe("Unable to bind to port " + listenPort);
		} catch (IOException e) {
			GlobalLogger.getLogger().warning("IO Exception while listening: " + listenPort + "; Might be force close");
		}
		
		System.out.println("The System is Down.");
	}
	
	/**
	 * @param args [port=7070]
	 */
	public static void main(String[] args) {
		GlobalLogger gl = new GlobalLogger(WorkManager.DEFAULT_LOG_PATH);
		
		// init server settings
		int listenPort;
        try {
            // Get port
        	listenPort = Integer.decode(args[0]).intValue();
            gl.logger.finest("Using port: " + listenPort);
        } catch (IndexOutOfBoundsException e) {
        	listenPort = WorkManager.DEFAULT_LISTENING_PORT;
        	gl.logger.warning("Using port: " + listenPort);
        }
        
        // Process in a while loop
        WorkManager.serveForever(listenPort, new ThreadedConnectionHandler());
	}
	
	/**
	 * Getter for the job distributor
	 * @return the local job distributor
	 */
	public static JobDistributor jobDisterbutor() {
		return WorkManager.localJobDistributor;
	}
	
	/**
	 * Return the inet address of the listening socket
	 * @return inet
	 */
	public static String getInetAddress() {
		//return WorkManager.serverInetAddress;
		return WorkManager.SERVER_NAME + ":" + Integer.toString(WorkManager.listeningPort);
	}
	
	/**
	 * Close the server socket
	 */
	public static void stopSock() {
		GlobalLogger.getLogger().severe("Closing server socket");
		if (null != WorkManager.serverSocket)
			try {
				WorkManager.serverSocket.close();
			} catch (IOException e) {
				GlobalLogger.getLogger().severe("IO Error while closing socket");
			}
	}

}
